#include "Rp2Geometry.h"
#include "Rp2Culler.h"
#include "Rp2Light.h"

using namespace Rp2;

RP2_IMPLEMENT_RTTI(Rp2, Geometry, Spatial);
RP2_IMPLEMENT_DEFAULT_NAME_ID(Geometry, Spatial);

//---------------------------------------------------------------------------------------------------
Geometry::Geometry()
	:
	ModelBound(BoundingVolume::Create())
{
	memset(States, 0, GlobalState::MAX_STATE_TYPE * sizeof(GlobalState*));
}
//---------------------------------------------------------------------------------------------------
Geometry::Geometry(VertexBuffer* pkVBuffer, IndexBuffer* pkIBuffer)
	:
	VBuffer(pkVBuffer),
	IBuffer(pkIBuffer),
	ModelBound(BoundingVolume::Create())
{
    memset(States,0,GlobalState::MAX_STATE_TYPE*sizeof(GlobalState*));
    UpdateModelBound();
}
//---------------------------------------------------------------------------------------------------
Geometry::~Geometry()
{
}
//---------------------------------------------------------------------------------------------------
void Geometry::GetVisibleSet(Culler& rkCuller, bool bNoCull)
{
	rkCuller.Insert(this, 0);
}
//---------------------------------------------------------------------------------------------------
void Geometry::UpdateMS(bool bUpdateNormals)
{
	UpdateModelBound();

	if (bUpdateNormals)
	{
		UpdateModelNormals();
	}
}
//---------------------------------------------------------------------------------------------------
void Geometry::UpdateModelBound()
{
	ModelBound->ComputeFromData(VBuffer);
}
//---------------------------------------------------------------------------------------------------
void Geometry::UpdateWorldBound()
{
	ModelBound->TransformBy(World, WorldBound);
}
//---------------------------------------------------------------------------------------------------
void Geometry::UpdateWorldData(double dAppTime)
{
	Spatial::UpdateWorldData(dAppTime);
	World.GetHomogeneous(HWorld);
}
//---------------------------------------------------------------------------------------------------
void Geometry::UpdateState(std::vector<GlobalState*>* akGStack, std::vector<Light*>* pkLStack)
{
	// Update global state
	int i;
	for (i = 0; i < GlobalState::MAX_STATE_TYPE; i++)
	{
		GlobalState* pkGState = 0;
		pkGState = akGStack[i].back();
		States[i] = pkGState;
	}

	// update lights
	int iLQuantity = (int)pkLStack->size();
	if (iLQuantity > 0)
	{
		for (i = 0; i < (int)m_kEffects.size(); i++)
		{
			if (m_kEffects[i]->IsDerived(LightingEffect::TYPE))
			{
				LightingEffect* pkLightEffect = StaticCast<LightingEffect>(m_kEffects[i]);
				pkLightEffect->DetachAllLights();
				for (i = 0; i < iLQuantity; i++)
				{		
					pkLightEffect->AttachLight((*pkLStack)[i]);
				}

				// set shaders
				pkLightEffect->Configure();
			}
		}
	}
	else
	{
		for (i = 0; i < (int)m_kEffects.size(); i++)
		{
			if (m_kEffects[i]->IsDerived(LightingEffect::TYPE))
			{
				LightingEffect* pkLightEffect = StaticCast<LightingEffect>(m_kEffects[i]);
				pkLightEffect->DetachAllLights();

				pkLightEffect->Configure();
			}
		}		
// 		if (m_spkLEffect)
// 		{
// 			if (m_kEffects.size() > 0)
// 			{
//                 // The first effect is m_spkLEffect.
// 				m_kEffects.erase(m_kEffects.begin());
// 			}
// 			m_spkLEffect = 0;
// 		}
	}
}
//---------------------------------------------------------------------------------------------------